/*****************************************************
 * jr generated file
 ****************************************************/
import edu.ucdavis.jr.*;
import edu.ucdavis.jr.jrx.*;
import java.rmi.*;
import java.io.Serializable;


import edu.ucdavis.jr.*;
import java.util.*;
import java.math.*;

public class DiffusionCountProcessor extends java.lang.Object {
    { JRinit(); }
    public static final String DBG = "DiffusionCountProcessor";
    public Op_DiffusionCountProcessorTovoid.JRProxyOp JRget_op_PUSH_DiffusionCountProcessorTovoid()
    {
        return op_PUSH_DiffusionCountProcessorTovoid;
    }
    
    public Op_DiffusionCountProcessorTovoid.JRProxyOp op_PUSH_DiffusionCountProcessorTovoid;
    
    public Op_doubleXdoubleXintTovoid.JRProxyOp JRget_op_PULL_doubleXdoubleXintTovoid()
    {
        return op_PULL_doubleXdoubleXintTovoid;
    }
    
    public Op_doubleXdoubleXintTovoid.JRProxyOp op_PULL_doubleXdoubleXintTovoid;
    
    public Op_DiffusionCountProcessorTovoid.JRProxyOp JRget_op_CONN_DiffusionCountProcessorTovoid()
    {
        return op_CONN_DiffusionCountProcessorTovoid;
    }
    
    public Op_DiffusionCountProcessorTovoid.JRProxyOp op_CONN_DiffusionCountProcessorTovoid;
    
    public Op_DiffusionCountProcessorTovoid.JRProxyOp JRget_op_DISC_DiffusionCountProcessorTovoid()
    {
        return op_DISC_DiffusionCountProcessorTovoid;
    }
    
    public Op_DiffusionCountProcessorTovoid.JRProxyOp op_DISC_DiffusionCountProcessorTovoid;
    
    public Op_DiffusionCountProcessorXbooleanTovoid.JRProxyOp JRget_op_RCON_DiffusionCountProcessorXbooleanTovoid()
    {
        return op_RCON_DiffusionCountProcessorXbooleanTovoid;
    }
    
    public Op_DiffusionCountProcessorXbooleanTovoid.JRProxyOp op_RCON_DiffusionCountProcessorXbooleanTovoid;
    
    public Op_DiffusionCountProcessorXbooleanTovoid.JRProxyOp JRget_op_RDIS_DiffusionCountProcessorXbooleanTovoid()
    {
        return op_RDIS_DiffusionCountProcessorXbooleanTovoid;
    }
    
    public Op_DiffusionCountProcessorXbooleanTovoid.JRProxyOp op_RDIS_DiffusionCountProcessorXbooleanTovoid;
    
    public double estimate = 0;
    public double count = 0;
    public int procId = 0;
    public int cycle = 0;
    public boolean connected = false;
    public boolean neighborConnected = false;
    public int neighborProcId = -1;
    public int cycleLimit = 0;
    public ArrayList neighbors = null;
    public Random random = new Random();
    
    public DiffusionCountProcessor(int procId) {
        super();
        this.procId = procId;
        JRprocess();
    }
    
    public void setNeighbors(ArrayList neighbors) {
        this.neighbors = neighbors;
        JRget_op_client_voidTovoid().send(jrvm.getTimestamp(), (edu.ucdavis.jr.RemoteHandler) null);
        JRget_op_server_voidTovoid().send(jrvm.getTimestamp(), (edu.ucdavis.jr.RemoteHandler) null);
        JRget_op_connectOp_voidTovoid().send(jrvm.getTimestamp(), (edu.ucdavis.jr.RemoteHandler) null);
        JRget_op_disconnectOp_voidTovoid().send(jrvm.getTimestamp(), (edu.ucdavis.jr.RemoteHandler) null);
    }
    
    private void client() {
        op_client_voidTovoid.call(jrvm.getTimestamp());
    }
    private void client(Op_voidTovoid.JRProxyOp retOp, Cap_voidTovoid fretOp, edu.ucdavis.jr.RemoteHandler handler)
    {
        try    {
            {
                JRLoop1: while (PlainDiffusion.warmup) ;
                JRLoop6: while (true) {
                    delay(10 * (cycle + 1));
                    DiffusionCountProcessor selectedNeighbor = null;
                    int ni = 0;
                    if (neighbors.size() > 1) {
                        ni = Math.abs(random.nextInt()) % neighbors.size();
                    }
                    selectedNeighbor = ((DiffusionCountProcessor)neighbors.get(ni));
                    JRLoop3: while (!connected) {
                        JRLoop2: while (neighborConnected) {
                            delay(-1);
                        }
                        DebugUtil.out("P(" + DebugUtil.df(procId) + ") SEND P(" + DebugUtil.df(selectedNeighbor.procId) + ") CONN est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ")", true);
                        selectedNeighbor.JRget_op_CONN_DiffusionCountProcessorTovoid().send(jrvm.getTimestamp(), (edu.ucdavis.jr.RemoteHandler) null, this);
                        DiffusionCountProcessor replyProc = null;
                        boolean accepted = false;
                        // Receive
                        {
                            jrvm.sendAndDie();
                            Recv_DiffusionCountProcessorXbooleanTovoid recv_DiffusionCountProcessorXbooleanTovoid = JRget_op_RCON_DiffusionCountProcessorXbooleanTovoid().recv();
                            replyProc = (DiffusionCountProcessor) recv_DiffusionCountProcessorXbooleanTovoid.arg0;
                            accepted = (boolean) recv_DiffusionCountProcessorXbooleanTovoid.arg1;
                            jrvm.ariseAndReceive();
                            if (recv_DiffusionCountProcessorXbooleanTovoid.retOp != null)
                                recv_DiffusionCountProcessorXbooleanTovoid.retOp.send(jrvm.getTimestamp());
                        }
                        // End Receive
                        DebugUtil.out("P(" + DebugUtil.df(procId) + ") RECV P(" + DebugUtil.df(replyProc.procId) + ") RCON est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ") status (" + DebugUtil.df(accepted) + ")", true);
                    }
                    DebugUtil.out("P(" + DebugUtil.df(procId) + ") CALL P(" + DebugUtil.df(selectedNeighbor.procId) + ") PUSH est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ")", true);
                    selectedNeighbor.JRget_op_PUSH_DiffusionCountProcessorTovoid().call(jrvm.getTimestamp(), this);
                    double neighborEstimate = -1;
                    double neighborCount = -1;
                    int neighborProcId = -1;
                    // Receive
                    {
                        jrvm.sendAndDie();
                        Recv_doubleXdoubleXintTovoid recv_doubleXdoubleXintTovoid = JRget_op_PULL_doubleXdoubleXintTovoid().recv();
                        neighborEstimate = (double) recv_doubleXdoubleXintTovoid.arg0;
                        neighborCount = (double) recv_doubleXdoubleXintTovoid.arg1;
                        neighborProcId = (int) recv_doubleXdoubleXintTovoid.arg2;
                        jrvm.ariseAndReceive();
                        if (recv_doubleXdoubleXintTovoid.retOp != null)
                            recv_doubleXdoubleXintTovoid.retOp.send(jrvm.getTimestamp());
                    }
                    // End Receive
                    DebugUtil.out("P(" + DebugUtil.df(procId) + ") RECV P(" + DebugUtil.df(neighborProcId) + ") PULL est (" + DebugUtil.df(neighborEstimate) + ") count (" + DebugUtil.df(neighborCount) + ") cycle (" + DebugUtil.df(cycle) + ")", true);
                    update(estimate, neighborEstimate);
                    JRLoop4: while (connected) {
                        DebugUtil.out("P(" + DebugUtil.df(procId) + ") SEND P(" + DebugUtil.df(selectedNeighbor.procId) + ") DISC est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ")", true);
                        selectedNeighbor.JRget_op_DISC_DiffusionCountProcessorTovoid().send(jrvm.getTimestamp(), (edu.ucdavis.jr.RemoteHandler) null, this);
                        DiffusionCountProcessor replyProc = null;
                        boolean accepted = false;
                        // Receive
                        {
                            jrvm.sendAndDie();
                            Recv_DiffusionCountProcessorXbooleanTovoid recv_DiffusionCountProcessorXbooleanTovoid = JRget_op_RDIS_DiffusionCountProcessorXbooleanTovoid().recv();
                            replyProc = (DiffusionCountProcessor) recv_DiffusionCountProcessorXbooleanTovoid.arg0;
                            accepted = (boolean) recv_DiffusionCountProcessorXbooleanTovoid.arg1;
                            jrvm.ariseAndReceive();
                            if (recv_DiffusionCountProcessorXbooleanTovoid.retOp != null)
                                recv_DiffusionCountProcessorXbooleanTovoid.retOp.send(jrvm.getTimestamp());
                        }
                        // End Receive
                        DebugUtil.out("P(" + DebugUtil.df(procId) + ") RECV P(" + DebugUtil.df(replyProc.procId) + ") RDIS est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ") status (" + DebugUtil.df(accepted) + ")", true);
                    }
                    if ((cycle + 1) > cycleLimit) {
                        JRLoop5: while (true) {
                            delay(-1);
                        }
                    } else {
                        cycle++;
                    }
                }
            }
        } catch (Exception JRe)    {
            if (retOp != null && fretOp == null)
            {
        	// if it is a forward cocall with handler
        	if ((handler != null) && !(JRe instanceof java.rmi.RemoteException))
        	    handler.JRhandler(JRe);
        	else
        	    // give preference to propagation through the call stack
        	    retOp.send(jrvm.getTimestamp(), JRe);
            }
            else if ((retOp != null) && (fretOp != null) && !(JRe instanceof java.rmi.RemoteException))
            {
        	// for COSTMT exception handling in operation
        	if (handler != null)
        	    handler.JRhandler(JRe);
        	fretOp.send(jrvm.getTimestamp(), handler);
            }
            else if ((handler != null) && !(JRe instanceof java.rmi.RemoteException))
            {
        	// this should only be for a send/forward
        	handler.JRhandler(JRe);
        	// can rethrow below just to get out of this method
            }
            // rethrow the proper type of exception
            // catch all
            throw new jrRuntimeError("Unhandled exception: " + JRe.toString());
        }
    }
    private Op_voidTovoid.JRProxyOp JRget_op_client_voidTovoid()
    {
        return op_client_voidTovoid;
    }
    
    public Op_voidTovoid.JRProxyOp op_client_voidTovoid;
    class ProcOp_voidTovoid_implclient extends ProcOp_voidTovoid_impl
    {
        DiffusionCountProcessor thisarg;
        public ProcOp_voidTovoid_implclient(DiffusionCountProcessor thisIn) throws RemoteException
        {
        thisarg = thisIn;
        }
        public void call(long JRtimestamp) throws RemoteException
        {
            jrvm.ariseAndReceive();  // from caller
            try    {
                jrvm.setTimestamp(JRtimestamp);
                thisarg.client(null, null, null);
            } finally {
                jrvm.sendAndDie();    // to caller
            }
        }
        class sendThread implements Runnable
        {
            Op_voidTovoid.JRProxyOp retOp;
            Cap_voidTovoid fretOp;
            edu.ucdavis.jr.RemoteHandler handler;

            public sendThread(Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler)
            {
                this.retOp = retOp;
                this.handler = handler;
            }
            public sendThread(Op_voidTovoid.JRProxyOp retOp, Cap_voidTovoid fretOp,edu.ucdavis.jr.RemoteHandler handler)
            {
                this.retOp = retOp;
                this.fretOp = fretOp;
                this.handler = handler;
            }
            public void run()
            {
                try    {
                    thisarg.client(this.retOp, this.fretOp, this.handler);
                } catch (Exception e) {/* should be safe to ignore this exception */}
                jrvm.threadDeath();
            }
        }
        public void send(long JRtimestamp) throws RemoteException
        {
            this.send(JRtimestamp, null, null, null);
        }
        public Cap_voidTovoid cosend(long JRtimestamp) throws RemoteException
        {
            return this.cosend(JRtimestamp, null, null, null);
        }
        public void send(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler) throws RemoteException
        {
            this.send(JRtimestamp, null, handler, null);
        }
        public Cap_voidTovoid cosend(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler) throws RemoteException
        {
            return this.cosend(JRtimestamp, null, handler, null);
        }
        public void send(long JRtimestamp, Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws RemoteException
        {
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, handler)).start();
        }
        public Cap_voidTovoid cosend(long JRtimestamp, Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws RemoteException
        {
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(null, handler)).start();
            Op_voidTovoid.JRProxyOp myretOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl());
            myretOp.send(jrvm.getTimestamp());
            return new Cap_voidTovoid(myretOp);
        }
        public Cap_voidTovoid cocall(long JRtimestamp) throws RemoteException
        {
            Op_voidTovoid.JRProxyOp retOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl(false));
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, null)).start();
            Cap_voidTovoid retCap = new Cap_voidTovoid(retOp);
            return retCap;
        }
        public Cap_voidTovoid cocall(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler, Cap_voidTovoid fretOp) throws RemoteException
        {
            Op_voidTovoid.JRProxyOp retOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl(false));
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, fretOp, handler)).start();
            Cap_voidTovoid retCap = new Cap_voidTovoid(retOp);
            return retCap;
        }
        public Recv_voidTovoid recv() throws RemoteException
        {
            /* This is an error */
            throw new jrRuntimeError("Receive invoked on an operation/operation capability associated with a method!");
        }
        public void deliverPendingMessages()
        {
            /* This is an error */
            throw new jrRuntimeError("Message delivery invoked on an operation associated with a method!");
        }
        public int length()
        {
            return 0;
        }
        public InOpIterator elements()
        {
            // This is an error
            throw new jrRuntimeError("Elements invoked on an operation / operation capability associated with a method!");
        }
        public InLock getLock()
        {
            // This is an error
            throw new jrRuntimeError("getLock invoked on an operation / operation capability associated with a method!");
        }
        public long getFirstTime()
        {
            // This is an error
            throw new jrRuntimeError("getFirstTime invoked on an operation / operation capability associated with a method!");
        }
        public boolean isRemote(String site)
        {
            // This is an error
            throw new jrRuntimeError("IsRemote invoked on an operation / operation capability associated with a method!");
        }
    }
    
    
    private void server() {
        op_server_voidTovoid.call(jrvm.getTimestamp());
    }
    private void server(Op_voidTovoid.JRProxyOp retOp, Cap_voidTovoid fretOp, edu.ucdavis.jr.RemoteHandler handler)
    {
        try    {
            {
                JRLoop7: while (true) {
                    DiffusionCountProcessor neighbor = null;
                    // Receive
                    {
                        jrvm.sendAndDie();
                        Recv_DiffusionCountProcessorTovoid recv_DiffusionCountProcessorTovoid = JRget_op_PUSH_DiffusionCountProcessorTovoid().recv();
                        neighbor = (DiffusionCountProcessor) recv_DiffusionCountProcessorTovoid.arg0;
                        jrvm.ariseAndReceive();
                        if (recv_DiffusionCountProcessorTovoid.retOp != null)
                            recv_DiffusionCountProcessorTovoid.retOp.send(jrvm.getTimestamp());
                    }
                    // End Receive
                    DebugUtil.out("P(" + DebugUtil.df(procId) + ") RECV P(" + DebugUtil.df(neighbor.procId) + ") PUSH est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ")", true);
                    DebugUtil.out("P(" + DebugUtil.df(procId) + ") CALL P(" + DebugUtil.df(neighbor.procId) + ") PULL est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ")", true);
                    double neighborEstimate = neighbor.estimate;
                    neighbor.JRget_op_PULL_doubleXdoubleXintTovoid().call(jrvm.getTimestamp(), estimate, count, procId);
                    update(estimate, neighborEstimate);
                }
            }
        } catch (Exception JRe)    {
            if (retOp != null && fretOp == null)
            {
        	// if it is a forward cocall with handler
        	if ((handler != null) && !(JRe instanceof java.rmi.RemoteException))
        	    handler.JRhandler(JRe);
        	else
        	    // give preference to propagation through the call stack
        	    retOp.send(jrvm.getTimestamp(), JRe);
            }
            else if ((retOp != null) && (fretOp != null) && !(JRe instanceof java.rmi.RemoteException))
            {
        	// for COSTMT exception handling in operation
        	if (handler != null)
        	    handler.JRhandler(JRe);
        	fretOp.send(jrvm.getTimestamp(), handler);
            }
            else if ((handler != null) && !(JRe instanceof java.rmi.RemoteException))
            {
        	// this should only be for a send/forward
        	handler.JRhandler(JRe);
        	// can rethrow below just to get out of this method
            }
            // rethrow the proper type of exception
            // catch all
            throw new jrRuntimeError("Unhandled exception: " + JRe.toString());
        }
    }
    private Op_voidTovoid.JRProxyOp JRget_op_server_voidTovoid()
    {
        return op_server_voidTovoid;
    }
    
    public Op_voidTovoid.JRProxyOp op_server_voidTovoid;
    class ProcOp_voidTovoid_implserver extends ProcOp_voidTovoid_impl
    {
        DiffusionCountProcessor thisarg;
        public ProcOp_voidTovoid_implserver(DiffusionCountProcessor thisIn) throws RemoteException
        {
        thisarg = thisIn;
        }
        public void call(long JRtimestamp) throws RemoteException
        {
            jrvm.ariseAndReceive();  // from caller
            try    {
                jrvm.setTimestamp(JRtimestamp);
                thisarg.server(null, null, null);
            } finally {
                jrvm.sendAndDie();    // to caller
            }
        }
        class sendThread implements Runnable
        {
            Op_voidTovoid.JRProxyOp retOp;
            Cap_voidTovoid fretOp;
            edu.ucdavis.jr.RemoteHandler handler;

            public sendThread(Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler)
            {
                this.retOp = retOp;
                this.handler = handler;
            }
            public sendThread(Op_voidTovoid.JRProxyOp retOp, Cap_voidTovoid fretOp,edu.ucdavis.jr.RemoteHandler handler)
            {
                this.retOp = retOp;
                this.fretOp = fretOp;
                this.handler = handler;
            }
            public void run()
            {
                try    {
                    thisarg.server(this.retOp, this.fretOp, this.handler);
                } catch (Exception e) {/* should be safe to ignore this exception */}
                jrvm.threadDeath();
            }
        }
        public void send(long JRtimestamp) throws RemoteException
        {
            this.send(JRtimestamp, null, null, null);
        }
        public Cap_voidTovoid cosend(long JRtimestamp) throws RemoteException
        {
            return this.cosend(JRtimestamp, null, null, null);
        }
        public void send(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler) throws RemoteException
        {
            this.send(JRtimestamp, null, handler, null);
        }
        public Cap_voidTovoid cosend(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler) throws RemoteException
        {
            return this.cosend(JRtimestamp, null, handler, null);
        }
        public void send(long JRtimestamp, Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws RemoteException
        {
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, handler)).start();
        }
        public Cap_voidTovoid cosend(long JRtimestamp, Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws RemoteException
        {
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(null, handler)).start();
            Op_voidTovoid.JRProxyOp myretOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl());
            myretOp.send(jrvm.getTimestamp());
            return new Cap_voidTovoid(myretOp);
        }
        public Cap_voidTovoid cocall(long JRtimestamp) throws RemoteException
        {
            Op_voidTovoid.JRProxyOp retOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl(false));
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, null)).start();
            Cap_voidTovoid retCap = new Cap_voidTovoid(retOp);
            return retCap;
        }
        public Cap_voidTovoid cocall(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler, Cap_voidTovoid fretOp) throws RemoteException
        {
            Op_voidTovoid.JRProxyOp retOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl(false));
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, fretOp, handler)).start();
            Cap_voidTovoid retCap = new Cap_voidTovoid(retOp);
            return retCap;
        }
        public Recv_voidTovoid recv() throws RemoteException
        {
            /* This is an error */
            throw new jrRuntimeError("Receive invoked on an operation/operation capability associated with a method!");
        }
        public void deliverPendingMessages()
        {
            /* This is an error */
            throw new jrRuntimeError("Message delivery invoked on an operation associated with a method!");
        }
        public int length()
        {
            return 0;
        }
        public InOpIterator elements()
        {
            // This is an error
            throw new jrRuntimeError("Elements invoked on an operation / operation capability associated with a method!");
        }
        public InLock getLock()
        {
            // This is an error
            throw new jrRuntimeError("getLock invoked on an operation / operation capability associated with a method!");
        }
        public long getFirstTime()
        {
            // This is an error
            throw new jrRuntimeError("getFirstTime invoked on an operation / operation capability associated with a method!");
        }
        public boolean isRemote(String site)
        {
            // This is an error
            throw new jrRuntimeError("IsRemote invoked on an operation / operation capability associated with a method!");
        }
    }
    
    
    private void connectOp() {
        op_connectOp_voidTovoid.call(jrvm.getTimestamp());
    }
    private void connectOp(Op_voidTovoid.JRProxyOp retOp, Cap_voidTovoid fretOp, edu.ucdavis.jr.RemoteHandler handler)
    {
        try    {
            {
                JRLoop8: while (true) {
                    DiffusionCountProcessor neighbor = null;
                    // Receive
                    {
                        jrvm.sendAndDie();
                        Recv_DiffusionCountProcessorTovoid recv_DiffusionCountProcessorTovoid = JRget_op_CONN_DiffusionCountProcessorTovoid().recv();
                        neighbor = (DiffusionCountProcessor) recv_DiffusionCountProcessorTovoid.arg0;
                        jrvm.ariseAndReceive();
                        if (recv_DiffusionCountProcessorTovoid.retOp != null)
                            recv_DiffusionCountProcessorTovoid.retOp.send(jrvm.getTimestamp());
                    }
                    // End Receive
                    DebugUtil.out("P(" + DebugUtil.df(procId) + ") RECV P(" + DebugUtil.df(neighbor.procId) + ") CONN est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ")", true);
                    if (!connected && !neighborConnected && !neighbor.connected && !neighbor.neighborConnected) {
                        connected = false;
                        neighborConnected = true;
                        neighborProcId = neighbor.procId;
                        neighbor.connected = true;
                        neighbor.neighborConnected = false;
                        neighbor.neighborProcId = procId;
                        DebugUtil.out("P(" + DebugUtil.df(procId) + ") CALL P(" + DebugUtil.df(neighbor.procId) + ") RCON est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ") status (" + DebugUtil.df(true) + ")", true);
                        neighbor.JRget_op_RCON_DiffusionCountProcessorXbooleanTovoid().call(jrvm.getTimestamp(), this, true);
                    } else {
                        DebugUtil.out("P(" + DebugUtil.df(procId) + ") CALL P(" + DebugUtil.df(neighbor.procId) + ") RCON est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ") status (" + DebugUtil.df(false) + ")", true);
                        neighbor.JRget_op_RCON_DiffusionCountProcessorXbooleanTovoid().call(jrvm.getTimestamp(), this, false);
                    }
                }
            }
        } catch (Exception JRe)    {
            if (retOp != null && fretOp == null)
            {
        	// if it is a forward cocall with handler
        	if ((handler != null) && !(JRe instanceof java.rmi.RemoteException))
        	    handler.JRhandler(JRe);
        	else
        	    // give preference to propagation through the call stack
        	    retOp.send(jrvm.getTimestamp(), JRe);
            }
            else if ((retOp != null) && (fretOp != null) && !(JRe instanceof java.rmi.RemoteException))
            {
        	// for COSTMT exception handling in operation
        	if (handler != null)
        	    handler.JRhandler(JRe);
        	fretOp.send(jrvm.getTimestamp(), handler);
            }
            else if ((handler != null) && !(JRe instanceof java.rmi.RemoteException))
            {
        	// this should only be for a send/forward
        	handler.JRhandler(JRe);
        	// can rethrow below just to get out of this method
            }
            // rethrow the proper type of exception
            // catch all
            throw new jrRuntimeError("Unhandled exception: " + JRe.toString());
        }
    }
    private Op_voidTovoid.JRProxyOp JRget_op_connectOp_voidTovoid()
    {
        return op_connectOp_voidTovoid;
    }
    
    public Op_voidTovoid.JRProxyOp op_connectOp_voidTovoid;
    class ProcOp_voidTovoid_implconnectOp extends ProcOp_voidTovoid_impl
    {
        DiffusionCountProcessor thisarg;
        public ProcOp_voidTovoid_implconnectOp(DiffusionCountProcessor thisIn) throws RemoteException
        {
        thisarg = thisIn;
        }
        public void call(long JRtimestamp) throws RemoteException
        {
            jrvm.ariseAndReceive();  // from caller
            try    {
                jrvm.setTimestamp(JRtimestamp);
                thisarg.connectOp(null, null, null);
            } finally {
                jrvm.sendAndDie();    // to caller
            }
        }
        class sendThread implements Runnable
        {
            Op_voidTovoid.JRProxyOp retOp;
            Cap_voidTovoid fretOp;
            edu.ucdavis.jr.RemoteHandler handler;

            public sendThread(Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler)
            {
                this.retOp = retOp;
                this.handler = handler;
            }
            public sendThread(Op_voidTovoid.JRProxyOp retOp, Cap_voidTovoid fretOp,edu.ucdavis.jr.RemoteHandler handler)
            {
                this.retOp = retOp;
                this.fretOp = fretOp;
                this.handler = handler;
            }
            public void run()
            {
                try    {
                    thisarg.connectOp(this.retOp, this.fretOp, this.handler);
                } catch (Exception e) {/* should be safe to ignore this exception */}
                jrvm.threadDeath();
            }
        }
        public void send(long JRtimestamp) throws RemoteException
        {
            this.send(JRtimestamp, null, null, null);
        }
        public Cap_voidTovoid cosend(long JRtimestamp) throws RemoteException
        {
            return this.cosend(JRtimestamp, null, null, null);
        }
        public void send(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler) throws RemoteException
        {
            this.send(JRtimestamp, null, handler, null);
        }
        public Cap_voidTovoid cosend(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler) throws RemoteException
        {
            return this.cosend(JRtimestamp, null, handler, null);
        }
        public void send(long JRtimestamp, Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws RemoteException
        {
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, handler)).start();
        }
        public Cap_voidTovoid cosend(long JRtimestamp, Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws RemoteException
        {
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(null, handler)).start();
            Op_voidTovoid.JRProxyOp myretOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl());
            myretOp.send(jrvm.getTimestamp());
            return new Cap_voidTovoid(myretOp);
        }
        public Cap_voidTovoid cocall(long JRtimestamp) throws RemoteException
        {
            Op_voidTovoid.JRProxyOp retOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl(false));
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, null)).start();
            Cap_voidTovoid retCap = new Cap_voidTovoid(retOp);
            return retCap;
        }
        public Cap_voidTovoid cocall(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler, Cap_voidTovoid fretOp) throws RemoteException
        {
            Op_voidTovoid.JRProxyOp retOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl(false));
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, fretOp, handler)).start();
            Cap_voidTovoid retCap = new Cap_voidTovoid(retOp);
            return retCap;
        }
        public Recv_voidTovoid recv() throws RemoteException
        {
            /* This is an error */
            throw new jrRuntimeError("Receive invoked on an operation/operation capability associated with a method!");
        }
        public void deliverPendingMessages()
        {
            /* This is an error */
            throw new jrRuntimeError("Message delivery invoked on an operation associated with a method!");
        }
        public int length()
        {
            return 0;
        }
        public InOpIterator elements()
        {
            // This is an error
            throw new jrRuntimeError("Elements invoked on an operation / operation capability associated with a method!");
        }
        public InLock getLock()
        {
            // This is an error
            throw new jrRuntimeError("getLock invoked on an operation / operation capability associated with a method!");
        }
        public long getFirstTime()
        {
            // This is an error
            throw new jrRuntimeError("getFirstTime invoked on an operation / operation capability associated with a method!");
        }
        public boolean isRemote(String site)
        {
            // This is an error
            throw new jrRuntimeError("IsRemote invoked on an operation / operation capability associated with a method!");
        }
    }
    
    
    private void disconnectOp() {
        op_disconnectOp_voidTovoid.call(jrvm.getTimestamp());
    }
    private void disconnectOp(Op_voidTovoid.JRProxyOp retOp, Cap_voidTovoid fretOp, edu.ucdavis.jr.RemoteHandler handler)
    {
        try    {
            {
                JRLoop9: while (true) {
                    DiffusionCountProcessor neighbor = null;
                    // Receive
                    {
                        jrvm.sendAndDie();
                        Recv_DiffusionCountProcessorTovoid recv_DiffusionCountProcessorTovoid = JRget_op_DISC_DiffusionCountProcessorTovoid().recv();
                        neighbor = (DiffusionCountProcessor) recv_DiffusionCountProcessorTovoid.arg0;
                        jrvm.ariseAndReceive();
                        if (recv_DiffusionCountProcessorTovoid.retOp != null)
                            recv_DiffusionCountProcessorTovoid.retOp.send(jrvm.getTimestamp());
                    }
                    // End Receive
                    DebugUtil.out("P(" + DebugUtil.df(procId) + ") RECV P(" + DebugUtil.df(neighbor.procId) + ") DISC est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ")", true);
                    if (neighbor.neighborProcId == procId) {
                        connected = false;
                        neighborConnected = false;
                        neighborProcId = -1;
                        neighbor.connected = false;
                        neighbor.neighborConnected = false;
                        neighbor.neighborProcId = -1;
                        DebugUtil.out("P(" + DebugUtil.df(procId) + ") CALL P(" + DebugUtil.df(neighbor.procId) + ") RDIS est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ") status (" + DebugUtil.df(true) + ")", true);
                        neighbor.JRget_op_RDIS_DiffusionCountProcessorXbooleanTovoid().call(jrvm.getTimestamp(), this, true);
                    } else {
                        DebugUtil.out("P(" + DebugUtil.df(procId) + ") CALL P(" + DebugUtil.df(neighbor.procId) + ") RDIS est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ") status (" + DebugUtil.df(false) + ")", true);
                        neighbor.JRget_op_RDIS_DiffusionCountProcessorXbooleanTovoid().call(jrvm.getTimestamp(), this, false);
                    }
                }
            }
        } catch (Exception JRe)    {
            if (retOp != null && fretOp == null)
            {
        	// if it is a forward cocall with handler
        	if ((handler != null) && !(JRe instanceof java.rmi.RemoteException))
        	    handler.JRhandler(JRe);
        	else
        	    // give preference to propagation through the call stack
        	    retOp.send(jrvm.getTimestamp(), JRe);
            }
            else if ((retOp != null) && (fretOp != null) && !(JRe instanceof java.rmi.RemoteException))
            {
        	// for COSTMT exception handling in operation
        	if (handler != null)
        	    handler.JRhandler(JRe);
        	fretOp.send(jrvm.getTimestamp(), handler);
            }
            else if ((handler != null) && !(JRe instanceof java.rmi.RemoteException))
            {
        	// this should only be for a send/forward
        	handler.JRhandler(JRe);
        	// can rethrow below just to get out of this method
            }
            // rethrow the proper type of exception
            // catch all
            throw new jrRuntimeError("Unhandled exception: " + JRe.toString());
        }
    }
    private Op_voidTovoid.JRProxyOp JRget_op_disconnectOp_voidTovoid()
    {
        return op_disconnectOp_voidTovoid;
    }
    
    public Op_voidTovoid.JRProxyOp op_disconnectOp_voidTovoid;
    class ProcOp_voidTovoid_impldisconnectOp extends ProcOp_voidTovoid_impl
    {
        DiffusionCountProcessor thisarg;
        public ProcOp_voidTovoid_impldisconnectOp(DiffusionCountProcessor thisIn) throws RemoteException
        {
        thisarg = thisIn;
        }
        public void call(long JRtimestamp) throws RemoteException
        {
            jrvm.ariseAndReceive();  // from caller
            try    {
                jrvm.setTimestamp(JRtimestamp);
                thisarg.disconnectOp(null, null, null);
            } finally {
                jrvm.sendAndDie();    // to caller
            }
        }
        class sendThread implements Runnable
        {
            Op_voidTovoid.JRProxyOp retOp;
            Cap_voidTovoid fretOp;
            edu.ucdavis.jr.RemoteHandler handler;

            public sendThread(Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler)
            {
                this.retOp = retOp;
                this.handler = handler;
            }
            public sendThread(Op_voidTovoid.JRProxyOp retOp, Cap_voidTovoid fretOp,edu.ucdavis.jr.RemoteHandler handler)
            {
                this.retOp = retOp;
                this.fretOp = fretOp;
                this.handler = handler;
            }
            public void run()
            {
                try    {
                    thisarg.disconnectOp(this.retOp, this.fretOp, this.handler);
                } catch (Exception e) {/* should be safe to ignore this exception */}
                jrvm.threadDeath();
            }
        }
        public void send(long JRtimestamp) throws RemoteException
        {
            this.send(JRtimestamp, null, null, null);
        }
        public Cap_voidTovoid cosend(long JRtimestamp) throws RemoteException
        {
            return this.cosend(JRtimestamp, null, null, null);
        }
        public void send(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler) throws RemoteException
        {
            this.send(JRtimestamp, null, handler, null);
        }
        public Cap_voidTovoid cosend(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler) throws RemoteException
        {
            return this.cosend(JRtimestamp, null, handler, null);
        }
        public void send(long JRtimestamp, Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws RemoteException
        {
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, handler)).start();
        }
        public Cap_voidTovoid cosend(long JRtimestamp, Op_voidTovoid.JRProxyOp retOp, edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws RemoteException
        {
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(null, handler)).start();
            Op_voidTovoid.JRProxyOp myretOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl());
            myretOp.send(jrvm.getTimestamp());
            return new Cap_voidTovoid(myretOp);
        }
        public Cap_voidTovoid cocall(long JRtimestamp) throws RemoteException
        {
            Op_voidTovoid.JRProxyOp retOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl(false));
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, null)).start();
            Cap_voidTovoid retCap = new Cap_voidTovoid(retOp);
            return retCap;
        }
        public Cap_voidTovoid cocall(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler, Cap_voidTovoid fretOp) throws RemoteException
        {
            Op_voidTovoid.JRProxyOp retOp = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl(false));
            jrvm.setTimestamp(JRtimestamp);
            jrvm.threadBirth();
            new Thread(new sendThread(retOp, fretOp, handler)).start();
            Cap_voidTovoid retCap = new Cap_voidTovoid(retOp);
            return retCap;
        }
        public Recv_voidTovoid recv() throws RemoteException
        {
            /* This is an error */
            throw new jrRuntimeError("Receive invoked on an operation/operation capability associated with a method!");
        }
        public void deliverPendingMessages()
        {
            /* This is an error */
            throw new jrRuntimeError("Message delivery invoked on an operation associated with a method!");
        }
        public int length()
        {
            return 0;
        }
        public InOpIterator elements()
        {
            // This is an error
            throw new jrRuntimeError("Elements invoked on an operation / operation capability associated with a method!");
        }
        public InLock getLock()
        {
            // This is an error
            throw new jrRuntimeError("getLock invoked on an operation / operation capability associated with a method!");
        }
        public long getFirstTime()
        {
            // This is an error
            throw new jrRuntimeError("getFirstTime invoked on an operation / operation capability associated with a method!");
        }
        public boolean isRemote(String site)
        {
            // This is an error
            throw new jrRuntimeError("IsRemote invoked on an operation / operation capability associated with a method!");
        }
    }
    
    
    private void update(double local, double neighbor) {
        if (local != neighbor) {
            estimate = (local + neighbor) / 2;
        }
        if (estimate > 0) count = 1 / estimate;
        DebugUtil.out("P(" + DebugUtil.df(procId) + ")             UPDT est (" + DebugUtil.df(estimate) + ") count (" + DebugUtil.df(count) + ") cycle (" + DebugUtil.df(cycle) + ")", true);
    }
    
    private void delay(int milliseconds) {
        if (milliseconds == -1) {
            milliseconds = Math.abs(random.nextInt() % 100) + 1;
        }
        try {
            Thread.sleep(milliseconds);
        } catch (java.lang.InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public void setEstimate(double newEstimate) {
        this.estimate = newEstimate;
    }
    
    public void setCycleLimit(int newLimit) {
        this.cycleLimit = newLimit;
    }
    protected boolean JRcalled = false;
    protected JRDiffusionCountProcessor jrresref;
    public Object JRgetjrresref()
    { try {return jrresref.clone(); } catch (Exception e) {/* not gonna happen */ return null; } }
    protected void JRinit() {
    	if(this.JRcalled) return;
    	try {
    	op_disconnectOp_voidTovoid = new Op_voidTovoid.JRProxyOp(new ProcOp_voidTovoid_impldisconnectOp(this));
    	op_connectOp_voidTovoid = new Op_voidTovoid.JRProxyOp(new ProcOp_voidTovoid_implconnectOp(this));
    	op_server_voidTovoid = new Op_voidTovoid.JRProxyOp(new ProcOp_voidTovoid_implserver(this));
    	op_client_voidTovoid = new Op_voidTovoid.JRProxyOp(new ProcOp_voidTovoid_implclient(this));
    	op_RDIS_DiffusionCountProcessorXbooleanTovoid = 
    	  new Op_DiffusionCountProcessorXbooleanTovoid.JRProxyOp(new InOp_DiffusionCountProcessorXbooleanTovoid_impl());
    	op_RCON_DiffusionCountProcessorXbooleanTovoid = 
    	  new Op_DiffusionCountProcessorXbooleanTovoid.JRProxyOp(new InOp_DiffusionCountProcessorXbooleanTovoid_impl());
    	op_DISC_DiffusionCountProcessorTovoid = 
    	  new Op_DiffusionCountProcessorTovoid.JRProxyOp(new InOp_DiffusionCountProcessorTovoid_impl());
    	op_CONN_DiffusionCountProcessorTovoid = 
    	  new Op_DiffusionCountProcessorTovoid.JRProxyOp(new InOp_DiffusionCountProcessorTovoid_impl());
    	op_PULL_doubleXdoubleXintTovoid = 
    	  new Op_doubleXdoubleXintTovoid.JRProxyOp(new InOp_doubleXdoubleXintTovoid_impl());
    	op_PUSH_DiffusionCountProcessorTovoid = 
    	  new Op_DiffusionCountProcessorTovoid.JRProxyOp(new InOp_DiffusionCountProcessorTovoid_impl());
    	} catch (Exception JRe)
    	{ throw new jrRuntimeError(JRe.toString()); }
    	jrresref = new JRDiffusionCountProcessor(op_disconnectOp_voidTovoid, op_connectOp_voidTovoid, op_server_voidTovoid, op_client_voidTovoid, op_RDIS_DiffusionCountProcessorXbooleanTovoid, op_RCON_DiffusionCountProcessorXbooleanTovoid, op_DISC_DiffusionCountProcessorTovoid, op_CONN_DiffusionCountProcessorTovoid, op_PULL_doubleXdoubleXintTovoid, op_PUSH_DiffusionCountProcessorTovoid);
    	this.JRcalled = true;
    }
    private boolean JRproc = false;
    private void JRprocess() {
    	if (JRproc) return;
    	JRproc = true;
    }
}
